-- Redis服务
-- Author: Colocasia
-- Date: 2018-04-01

local skynet = require "skynet";
require "skynet.manager";
local redis = require "skynet.db.redis";
local log = require "log";


local us_redis = {};
local pool = {};

local maxconnect = nil;

local function getconn(key)
    assert(string.len(key) > 0, 'invalid redis key ' .. key)
    local hash_num = string.byte(key, 1) + string.byte(key, #key)
    local db = pool[(hash_num%maxconnect)+1];
    return db;
end

function us_redis.test()
    local db = pool[1];
    assert(db, "redis pool error")
    db:del "C"
    -- db:set("A", "hello")
    -- db:set("B", "world")
    db:sadd("C", "one")

    log.print(db:get("A"))
    log.print(db:get("B"))
end

function us_redis.set(key, value)
    local db = getconn(key);
    local rt = db:set(key, value);
    return rt;
end

function us_redis.get(key)
    local db = getconn(key);
    local rt = db:get(key);
    log.printf("redis get %s ==> %s", key, rt);
    return rt;
end

function us_redis.del(key)
    local db = getconn(key);
    local rt = db:del(key);
    return rt;
end

function us_redis.incr(key)
    local db = getconn(key);
    local rt = db:incr(key);
    return rt;
end

function us_redis.hmset(key, tvalues)
    local db = getconn(key);
    local rt = db:hmset(key, table.unpack(tvalues));
    return rt;
end

function us_redis.hmget(key, ...)
    if not key then return end
    local db = getconn(key);
    local rt = db:hmget(key, ...);
    return rt;
end

function us_redis.hset(key, field, value)
    local db = getconn(key);
    local rt = db:hset(key, field, value);
    return rt;
end

function us_redis.hget(key, field)
    local db = getconn(key);
    local rt = db:hget(key, field);
    return rt;
end

function us_redis.hgetall(key)
    local db = getconn(key);
    local rt = db:hgetall(key);
    return rt;
end

function us_redis.zadd(key, score, member)
    local db = getconn(key);
    local rt = db:zadd(key, score, member);
    return rt;
end

function us_redis.zrange(key, from, to)
    local db = getconn(key);
    local rt = db:zrange(key, from, to);
    return rt;
end

function us_redis.zrevrange(key, from, to, score)
    local db = getconn(key);
    local rt;
    if not score then
        rt = db:zrevrange(key, from, to);
    else
        rt = db:zrevrange(key, from, to, score);
    end
    return rt;
end

function us_redis.zrank(key, member)
    local db = getconn(key);
    local rt = db:zrank(key, member);
    return rt;
end

function us_redis.zrevrank(key, member)
    local db = getconn(key);
    local rt = db:zrevrank(key, member);
    return rt;
end

function us_redis.zscore(key, score)
    local db = getconn(key);
    local rt = db:zscore(key, score);
    return rt;
end

function us_redis.zcount(key, from, to)
    local db = getconn(key);
    local rt = db:zcount(key, from, to);
    return rt;
end

function us_redis.zcard(key)
    local db = getconn(key);
    local rt = db:zcard(key);
    return rt;
end

function us_redis.expire(key, time)
    local db = getconn(key);
    local rt = db:expire(key, time);
    return rt;
end

function us_redis.start()
    maxconnect = 1;
    for i=1, maxconnect do
        local db = redis.connect({
            host = "127.0.0.1",
            port = 6379,
            auth = "180506",
            db = 0,
        })

        if db then
            -- db:flushdb();       -- 测试期清空
            pool[i] = db;
        else
            log.print("us_redis connect error");
        end
    end
    -- us_redis.test();
end

function us_redis.init()
    skynet.dispatch("lua", function(session, source, cmd, ...)
        local f = assert(us_redis[cmd], "us_redis cmd=>"..cmd.." not found");
        skynet.retpack(f(...));
    end)
    skynet.register(SERVICE_NAME);
end

skynet.start(us_redis.init);

